/*
 * Copyright 2008-2009 Daniel Cachapa <cachapa@gmail.com>
 * 
 * This program is distributed under the terms of the GNU General Public Licence Version 3
 * The licence can be read in its entirety in the LICENSE.txt file accompaning this source code,
 * or at: http://www.gnu.org/copyleft/gpl.html
 * 
 * This file is part of WeightWatch.
 *
 * WeightWatch is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * WeightWatch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the WeightWatch source code. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package net.cachapa.weightwatch.ui;

import net.cachapa.weightwatch.util.MyDate;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Display;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.Form;
import com.sun.lwuit.Label;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.animations.Transition;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BoxLayout;
import com.sun.lwuit.plaf.Style;
import net.cachapa.weightwatch.Bmi;
import net.cachapa.weightwatch.Value;
import net.cachapa.weightwatch.util.L;

public class MainForm extends Form implements ActionListener {

	private static final int MODE_MONTH = 1;
	private static final int MODE_YEAR = 2;
	private static final int MODE_COMPLETE = 3;
	
	private Application application;
	private Label currentChartLabel,  replacementChartLabel;
	private Transition prevChartTransition, nextChartTransition;
	private Transition slideChartDownTransition, slideChartUpTransition;
	private MyDate currentDateMonth, currentDateYear;
	private int chartWidth,  chartHeight;
	private Label bmiLabel;
	private int mode = 1;
	private Command insertCommand;
	private Command preferencesCommand;
	private Command exportChartCommand;
	private Command quitCommand;

	public MainForm(Application application) {
		this.setTitle("WeightWatch");
		this.application = application;
		
		this.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
		this.setMenuTransitions(CommonTransitions.createSlide(CommonTransitions.SLIDE_VERTICAL, true, 200), CommonTransitions.createEmpty());
		
		currentDateMonth = new MyDate();
		currentDateYear = new MyDate();
		
		currentChartLabel = new Label();
		Style labelStyle = currentChartLabel.getStyle();
		int margin = labelStyle.getMargin(LEFT) + labelStyle.getMargin(RIGHT) + labelStyle.getPadding(LEFT) + labelStyle.getPadding(RIGHT) + currentChartLabel.getGap() * 2;
		chartWidth = this.getLayoutWidth() - margin;
		chartHeight = this.getHeight();
		chartHeight -= this.getStyle().getFont().getHeight() * 4; // Title, softbuttons, chart title and bmi label
		chartHeight -= 36; // Accounts for the margins and paddings in the controls
		
		currentChartLabel.setAlignment(CENTER);
		currentChartLabel.setTextPosition(Component.TOP);
		this.addComponent(currentChartLabel);
				
		bmiLabel = new Label();
		bmiLabel.setAlignment(CENTER);
		this.addComponent(bmiLabel);

		replacementChartLabel = new Label();
		replacementChartLabel.setAlignment(CENTER);
		replacementChartLabel.setTextPosition(Component.TOP);

		/*** Image Transitions ***/
		prevChartTransition = CommonTransitions.createSlide(
			CommonTransitions.SLIDE_HORIZONTAL, true, 250);
		nextChartTransition = CommonTransitions.createSlide(
			CommonTransitions.SLIDE_HORIZONTAL, false, 250);
		slideChartDownTransition = CommonTransitions.createSlide(
			CommonTransitions.SLIDE_VERTICAL, false, 250);
		slideChartUpTransition = CommonTransitions.createSlide(
			CommonTransitions.SLIDE_VERTICAL, true, 250);

		this.addGameKeyListener(Display.GAME_UP, this);
		this.addGameKeyListener(Display.GAME_DOWN, this);
		this.addGameKeyListener(Display.GAME_LEFT, this);
		this.addGameKeyListener(Display.GAME_RIGHT, this);
		
		insertCommand = new Command("insert");
		preferencesCommand = new Command("preferences");
//		exportChartCommand = new Command("Test file browser");
		quitCommand = new Command("quit");
		this.addCommand(insertCommand);
		this.addCommand(preferencesCommand);
//		this.addCommand(exportChartCommand);
		this.addCommand(quitCommand);
		this.setBackCommand(quitCommand);
		this.setCommandListener(this);
	}

	public void show() {
		// Update the chart
		if (mode == MODE_COMPLETE) {
			currentChartLabel.setIcon(application.getWeightWatch().drawCompleteChart(chartWidth, chartHeight));
			MyDate startDate = ((Value)application.getWeightWatch().getFullDatabase().firstElement()).date;
			MyDate endDate = ((Value)application.getWeightWatch().getFullDatabase().lastElement()).date;
			replacementChartLabel.setText(startDate.toShortString() + " - " + endDate.toShortString());
		}
		else if (mode == MODE_MONTH) {
			currentChartLabel.setIcon(application.getWeightWatch().drawMonthChart(currentDateMonth, chartWidth, chartHeight));
			currentChartLabel.setText(currentDateMonth.getMonthName() + " " + currentDateMonth.getYear());
		}
		else {
			currentChartLabel.setIcon(application.getWeightWatch().drawYearChart(currentDateYear, chartWidth, chartHeight));
			currentChartLabel.setText(currentDateYear.getYear() + "");
		}
		
		// Update the BMI label
		double bmi = application.getWeightWatch().getCurrentBmi();
		if (bmi == 0) {
			bmiLabel.setText(" ");
		}
		else {
			bmiLabel.setText(L.l("bmi") + ": " + bmi + " (" + Bmi.getLevelName(bmi) + ")");
		}
		
		super.show();
	}

	public void actionPerformed(ActionEvent ae) {
		Object source = ae.getSource();
		if (source == this) {
			switch (ae.getKeyEvent()) {
				case Display.GAME_UP:
					if (mode == MODE_MONTH) {
						replacementChartLabel.setIcon(application.getWeightWatch().drawCompleteChart(chartWidth, chartHeight));
						MyDate startDate = ((Value)application.getWeightWatch().getFullDatabase().firstElement()).date;
						MyDate endDate = ((Value)application.getWeightWatch().getFullDatabase().lastElement()).date;
						replacementChartLabel.setText(startDate.toShortString() + " - " + endDate.toShortString());
						replace(currentChartLabel, replacementChartLabel, slideChartUpTransition);
						mode = MODE_COMPLETE;
					}
					else if (mode == MODE_YEAR) {
						replacementChartLabel.setIcon(application.getWeightWatch().drawMonthChart(currentDateMonth, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateMonth.getMonthName() + " " + currentDateMonth.getYear());
						replace(currentChartLabel, replacementChartLabel, slideChartUpTransition);
						mode = MODE_MONTH;
					}
					else {
						return;
					}
					break;
					
				case Display.GAME_DOWN:
					if (mode == MODE_COMPLETE) {
						replacementChartLabel.setIcon(application.getWeightWatch().drawMonthChart(currentDateMonth, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateMonth.getMonthName() + " " + currentDateMonth.getYear());
						replace(currentChartLabel, replacementChartLabel, slideChartDownTransition);
						mode = MODE_MONTH;
					}
					else if (mode == MODE_MONTH) {
						replacementChartLabel.setIcon(application.getWeightWatch().drawYearChart(currentDateYear, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateYear.getYear()+"");
						replace(currentChartLabel, replacementChartLabel, slideChartDownTransition);
						mode = MODE_YEAR;
					}
					else {
						return;
					}
					break;
					
				case Display.GAME_LEFT:
					if (mode == MODE_COMPLETE) {
						return;
					}
					else if (mode == MODE_YEAR) {
						currentDateYear.retreatYear();
						replacementChartLabel.setIcon(application.getWeightWatch().drawYearChart(currentDateYear, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateYear.getYear()+"");
						replace(currentChartLabel, replacementChartLabel, prevChartTransition);
					}
					else {
						currentDateMonth.retreatMonth();
						replacementChartLabel.setIcon(application.getWeightWatch().drawMonthChart(currentDateMonth, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateMonth.getMonthName() + " " + currentDateMonth.getYear());
						replace(currentChartLabel, replacementChartLabel, prevChartTransition);
					}
					break;

				case Display.GAME_RIGHT:
					if (mode == MODE_COMPLETE) {
						return;
					}
					else if (mode == MODE_YEAR) {
						currentDateYear.advanceYear();
						replacementChartLabel.setIcon(application.getWeightWatch().drawYearChart(currentDateYear, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateYear.getYear()+"");
						replace(currentChartLabel, replacementChartLabel, nextChartTransition);
					}
					else {
						currentDateMonth.advanceMonth();
						replacementChartLabel.setIcon(application.getWeightWatch().drawMonthChart(currentDateMonth, chartWidth, chartHeight));
						replacementChartLabel.setText(currentDateMonth.getMonthName() + " " + currentDateMonth.getYear());
						replace(currentChartLabel, replacementChartLabel, nextChartTransition);
					}
					break;
			}
			Label switchLabel = currentChartLabel;
			currentChartLabel = replacementChartLabel;
			replacementChartLabel = switchLabel;
		}
		
		else if (source == insertCommand) {
			application.performAction(Application.SHOW_ADD_VALUE_FORM);
		}
		
		else if (source == preferencesCommand) {
			application.performAction(Application.SHOW_PREFERENCES_FORM);
		}
		
//		else if (source == exportChartCommand) {
//			FileChooser fc = new FileChooser();
//			fc.show();
			
			
			
//			Image chart;
//			if (mode == MODE_MONTH) {
//				chart = application.getWeightWatch().drawMonthChart(currentDate, 400, 300);
//			}
//			else {
//				chart = application.getWeightWatch().drawYearChart(currentDate, 400, 300);
//			}
//			byte[] pngData = Encoder.toPNG(chart);
//
//			FileConnection file = null;
//			OutputStream os = null;
//			try {
//				file = (FileConnection) Connector.open("file:///e:/Other/test.png", Connector.READ_WRITE);
//				if (!file.exists()) {
//					file.create();
//				} else {
//					file.truncate(0);
//				}
//				os = file.openOutputStream();
//				os.write(pngData);
//				os.flush();
//			} catch (Exception ex) {
//				Dialog.show("Error writing file", ex.getMessage(), "ok", "ok");
//			} finally {
//				try {
//					if (os != null) {
//						os.close();
//					}
//					if (file != null) {
//						file.close();
//					}
//				} catch (Exception ex) {
//					Dialog.show("Error closing write", ex.getMessage(), "ok", "ok");
//				}
//			}
//		}
		
		else if (source == quitCommand) {
			application.performAction(Application.QUIT);
		}
	}
}
